package com.jule.miaozhuapc.webSocket.control;

import com.jule.miaozhuapc.service.GameService;
import com.jule.miaozhuapc.webSocket.WawaControl;
import com.jule.miaozhuapc.webSocket.WawaS1Socket.S1SocketUser;
import com.jule.miaozhuapc.webSocket.WawaS1Socket.S1ThreadWriter;
import com.jule.miaozhuapc.webSocket.WebSocketSendMessageUtil;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.*;

public class WawaControlWebSocket extends TextWebSocketHandler {

    @Autowired
    private GameService gameService;

    private Logger logger = Logger.getLogger(WawaControlWebSocket.class);
    /**
     * 所有 房间内的用户
     */
    public static Map<Integer, List<WebSocketSession>> seeDatas = new HashMap<Integer, List<WebSocketSession>>();

    /**
     * 每个房间 对应的玩家对象
     */
    public  static  Map<Integer, GameUserBean> PlayData = new HashMap<Integer, GameUserBean>();

    /**
     *  每个房间与服务1连接socket， 和s1User
     */
    public static Map<Integer, S1SocketUser> RoomSocketUser = new HashMap<>();

    /**
     *  服务器1房间使用情况
     */
    public static Map<Integer, Boolean> S1RoomUse = new HashMap<>();

    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("新用户加 sessionId = " + session.getId());
    }

    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.info("用户退出 sessionId = " + session.getId());
        removeUser(session);
    }

    /**
     * js调用websocket.send时候，会调用该方法
     */
    @SuppressWarnings({"unused", "unlikely-arg-type"})
    @Override
    protected void handleTextMessage(final WebSocketSession session, TextMessage message) throws Exception {

        // super.handleTextMessage(session, message);
        // 接收用户消息
        System.out.println("接收到消息:" + message.getPayload());
        System.out.println(message.getPayload());
        try {
            JSONObject obj = new JSONObject();

            obj = new JSONObject(message.getPayload().trim());
            String type = obj.getString("type"); // 数据类型
            String data = obj.getString("data"); // 数据值
            String extra = obj.getString("extra"); // 备注
            Integer room = Integer.parseInt(obj.getString("room")); // 房间号
            logger.info( obj);

            // 加入房间
            if (WawaControl.ROOM.toString().equals(type)) {
                if (!seeDatas.containsKey(room)) {
                    seeDatas.put(room,new ArrayList<WebSocketSession>() );
                    List<WebSocketSession> sessions = seeDatas.get(room);
                    seeDatas.get(room).add(session);
                } else {
                    if (!seeDatas.get(room).contains(session)) {
                        seeDatas.get(room).add(session);
                    }
                }
                //发送房间使用情况
                if (PlayData.get(room) == null || PlayData.get(room).getSession() == session) {
                    //可以开始
                    new WebSocketSendMessageUtil(WawaControl.CANSTART).sendOne(session);
                } else {
                    // 不可以开始
                    new WebSocketSendMessageUtil(WawaControl.CANNOTSTART).sendOne(session);
                    // 房间游戏者
                    new WebSocketSendMessageUtil(WawaControl.PLAYER).setData(PlayData.get(room).getWxPic()).sendOne(session);
                }

                // 开始 游戏
            } else if (WawaControl.START.toString().equals(type)) {
                // 查看房间是否空闲
                // 房间有人 并且不是自己
                if (PlayData.containsKey(room) && PlayData.get(room) != null && PlayData.get(room).getSession() != session) {
                    // 房间有人
                    new WebSocketSendMessageUtil(WawaControl.CANNOTSTART).sendOne(session);
                } else if( !PlayData.containsKey (room) || ( PlayData.containsKey(room) && PlayData.get(room) == null)  ||(PlayData.containsKey(room) && !PlayData.get(room).getIsPay())) {
                    // 扣款
                    GameUserBean gameUser = gameService.StartGame(Long.parseLong(data), (long)room);
                    if (gameUser == null || !gameUser.getIsPay()) {
                        if (gameUser.getUserId() != null && gameUser.getCoin() != null) {
                            // 扣款失败 没钱
                            new WebSocketSendMessageUtil(WawaControl.NOTAVAILABLE).setData(gameUser.getCoin()).setExTra(WawaControl.NOMONEY.toString()).sendOne(session);
                        } else {
                            // 扣款失败
                            new WebSocketSendMessageUtil(WawaControl.NOTAVAILABLE).sendOne(session);
                        }
                    } else {
                        gameUser.setSession(session);
                        // 添加到游戏列表
                        PlayData.put(room, gameUser);
//                        //可以开始
//                        new WebSocketSendMessageUtil(WawaControl.AVAILABLE).setData(gameUser.getCoin()).sendOne(session);
//                        // 房间游戏者
//                        new WebSocketSendMessageUtil(WawaControl.PLAYER).setData(PlayData.get(room).getWxPic()).sendOne(session);
//                        //给其它用户发送不能开始游戏
//                        new WebSocketSendMessageUtil(WawaControl.CANNOTSTART).excludeSession(session).sendList(seeDatas.get(room));

                        // 给服务器1开始游戏
                        new S1ThreadWriter(RoomSocketUser.get(room).getSocket(), "#"+room+"$$START$$"+RoomSocketUser.get(room).getS1UserId()+"#").start();
                    }
                } else {
                    // 重复开始
                    new WebSocketSendMessageUtil(WawaControl.AVAILABLE).setExTra("扣钱重复").sendOne(session);
                    System.out.println(" 扣钱重复开始" + session.getId());
                }
                // 发送指令
            } else if (WawaControl.CMD.toString().equals(type)) {
                if (PlayData.containsKey(room) && PlayData.get(room).getSession() == session && PlayData.get(room).getIsPay()) {
                    //  给服务器1开始游戏指令
                    new S1ThreadWriter(RoomSocketUser.get(room).getSocket(), "#"+room+"$$"+data+"$$"+RoomSocketUser.get(room).getS1UserId()+"#").start();
                } else {
                    // 非法开始
                    System.out.println("非法的" + session.getId());
                }
                // 退出
            } else {
                // 未知 消息
                System.out.println("未知消息" + session.getId());
            }
        } catch (Exception e) {
            e.getMessage();
            e.printStackTrace();
            //FIXME
            session.sendMessage(new TextMessage(" C 错误消息 " + message.toString()));
            return;
        }

    }

    /**
     * 异常
     */
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

        logger.info("异常 sessionId = " + session.getId());
        removeUser(session);
    }

    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 移除用户
     *
     * @param session
     * @throws Exception
     */
    @SuppressWarnings({"unused", "unlikely-arg-type"})
    private void removeUser(WebSocketSession session) throws Exception {
        // seeDatas 移除用户
        Set<Integer> set;
        Iterator<Integer> iter;
        try {
            set = seeDatas.keySet();
            iter = set.iterator();
            while (iter.hasNext()) {
                String key = iter.next().toString();
                logger.info("移除 session " + session);
                if (seeDatas.get(Integer.parseInt(key)).contains(session)) {
                    seeDatas.get(Integer.parseInt(key)).remove(session);
                    break;
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // playDara 移除用户
        try {
            Set<Integer> set2 = PlayData.keySet();
            Iterator<Integer> iter2 = set2.iterator();
            while (iter2.hasNext()) {
                String key = iter2.next().toString();
                logger.info("移除 session " + session);
                if (PlayData.get(Integer.parseInt(key)).getSession() == session) {
                    PlayData.remove(Integer.parseInt(key));
                    break;
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 关闭 session
        try {
            if (session.isOpen()) {
                session.close();
            }
        }catch (Exception e){

        }
    }

    //游戏成功回调
    public  void  GameOver(Integer roomId, String gameReturn){
        gameService.GameOver(WawaControlWebSocket.PlayData.get(roomId), "SUCCESS".equals(gameReturn));
    }
}
